package com.demo.chapter7parallel;

import java.util.function.Function;
import java.util.stream.Stream;

/**
 * 比较一下并行流、串行流、原始方式
 * 
 * @author Administrator
 *
 */
public class ParallelStreamsCompare {

	//传统java实现
	public static long iterativeSum(long n) {
		long result = 0;
		for (long i = 0; i <= n; i++) {
			result += i;
		}
		return result;
	}

	//串行流
	public static long sequentialSum(long n) {
		return Stream.iterate(1L, i -> i + 1).limit(n).reduce(Long::sum).get();
	}

	//并行流
	public static long parallelSum(long n) {
		return Stream.iterate(1L, i -> i + 1).limit(n).parallel()
				.reduce(Long::sum).get();
	}
	
	//测试方法
	public static long measureSumPref(Function<Long, Long> adder, long n){
		long fast = Long.MAX_VALUE;
		for(int i=0; i<10; i++){
			long start = System.nanoTime();
			adder.apply(n);
			long duration = (System.nanoTime() - start) / 1000000;
			if(duration < fast){
				fast = duration;
			}
		}
		return fast;
	}
	
	//结果很遗憾，并行流的性能最差，原因：
	//1、iterate生成的是装箱对象，必须拆箱成数字
	//2、很难把iterate分成多个独立的块来执行，因为每次应用这个函数都要依赖于前一次应用的结果
	public static void main(String[] args) {
		System.out.println("传统java实现用时：" + measureSumPref(ParallelStreamsCompare::iterativeSum, 2000000) + "msecs");
		System.out.println("串行流用时：" + measureSumPref(ParallelStreamsCompare::sequentialSum, 2000000) + "msecs");
		System.out.println("并行流用时：" + measureSumPref(ParallelStreamsCompare::parallelSum, 2000000) + "msecs");
	}

}
